use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::Instruction, rtda::Frame};


// Negate double
#[derive(Debug, Default)]
pub struct DNEG {}

impl Instruction for DNEG {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let val = stack.borrow_mut().pop_double();
        stack.borrow_mut().push_double(-val);
    }
}

// Negate float
#[derive(Debug, Default)]
pub struct FNEG {}

impl Instruction for FNEG {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let val = stack.borrow_mut().pop_float();
        stack.borrow_mut().push_float(-val);
    }
}


// Negate int
#[derive(Debug, Default)]
pub struct INEG {}

impl Instruction for INEG {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let val = stack.borrow_mut().pop_int();
        stack.borrow_mut().push_int(-val);
    }
}

// Negate long
#[derive(Debug, Default)]
pub struct LNEG {}

impl Instruction for LNEG {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let val = stack.borrow_mut().pop_long();
        stack.borrow_mut().push_long(-val);
    }
}